package com.tuanzi.loan.business.repository.credithousekeeper.impl;

import com.tuanzi.loan.business.repository.credithousekeeper.CreditCompensatoryWithdrawOrderRepository;
import com.tuanzi.loan.core.repository.JOOQBaseRepositoryPlus;
import com.tuanzi.loan.vo.request.credithousekeeper.CreditCompensatoryWithdrawOrderRequest;
import com.tuanzi.loan.vo.response.credithousekeeper.CreditCompensatoryWithdrawOrderResponse;
import com.tuanzi.server.loan_base.constant.CardCompensationOrderStatus;
import com.tuanzi.server.loan_base.util.PhoneNumNideUtil;
import org.jooq.*;
import org.jooq.impl.DSL;
import org.jooq.impl.TableImpl;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Repository;

import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.tuanzi.loan.generated.jooq.loan.tables.LoanCardCompensationOrder.LOAN_CARD_COMPENSATION_ORDER;
import static com.tuanzi.loan.generated.jooq.loan.tables.LoanCompensationUserCard.LOAN_COMPENSATION_USER_CARD;

/**
* @param:
* @Description:    信用卡代偿订单查询sql
* @Author:         xionghao
* @CreateDate:      2018-07-18
*/
@SuppressWarnings({ "rawtypes" })
@Repository
public class CreditCompensatoryWithdrawOrderRepositoryImpl extends JOOQBaseRepositoryPlus implements CreditCompensatoryWithdrawOrderRepository{
    @Override
    protected TableImpl getTable() {
        return LOAN_CARD_COMPENSATION_ORDER;
    }

    private String WITHDRAW_BANK_NAME = "WITHDRAW_BANK";
    private String WITHDRAW_BANK_NUM = "WITHDRAW_CARD_NUM";
    private String WITHDRAW_NO = "WITHDRAW_CARD_NO";

    private static Map<Integer,String> ORDER_STATUS_MAP = new HashMap<>();
    static {
        ORDER_STATUS_MAP.put(11,"处理中");
        ORDER_STATUS_MAP.put(12,"成功");
        ORDER_STATUS_MAP.put(13,"旧版订单失败");
        ORDER_STATUS_MAP.put(15,"旧版订单异常");
        ORDER_STATUS_MAP.put(16,"已支付");
        ORDER_STATUS_MAP.put(17,"扣款失败");
        ORDER_STATUS_MAP.put(19,"打款失败");
    }

    private static Map<Integer,String> ORDER_TYPE = new HashMap<>();
    static {
        ORDER_TYPE.put(1,"取现");
        ORDER_TYPE.put(0,"代偿");
    }

    @Override
    public Page<CreditCompensatoryWithdrawOrderResponse> list(CreditCompensatoryWithdrawOrderRequest searchRequest, Pageable pageable) {
        //默认展示上一天的数据
        if (searchRequest.getStartDate() == null && searchRequest.getEndDate() == null){
            searchRequest.setStartDate(new Date());
        }


        SelectQuery selectQuery = this.createQuery(searchRequest);
        return search(selectQuery,pageable,record -> createResponseByRecord(record));
    }

    /**
     * 根据返回的记录生成实体
     */
    private CreditCompensatoryWithdrawOrderResponse createResponseByRecord(Record record) {

        CreditCompensatoryWithdrawOrderResponse response = new CreditCompensatoryWithdrawOrderResponse();
        response.setCreateTime(record.get(LOAN_CARD_COMPENSATION_ORDER.CTIME));
        response.setOrderId(record.get(LOAN_CARD_COMPENSATION_ORDER.ID));
        response.setChannel(record.get(LOAN_CARD_COMPENSATION_ORDER.CHANNEL));
        //产品id
        response.setPrdocu_id(record.get(LOAN_CARD_COMPENSATION_ORDER.PRODUCT_ID));
        response.setPetname(PhoneNumNideUtil.hideName(record.get(LOAN_CARD_COMPENSATION_ORDER.PETNAME)));
        response.setMobnum(record.get(LOAN_CARD_COMPENSATION_ORDER.BANK_MOBILE_NUM));
        response.setIdcard(PhoneNumNideUtil.hideIdCard(record.get(LOAN_CARD_COMPENSATION_ORDER.IDCARD)));
        //订单类型
        int orderType = record.get(LOAN_CARD_COMPENSATION_ORDER.ORDER_TYPE);

        response.setType(ORDER_TYPE.get(orderType));
        response.setAmount(record.get(LOAN_CARD_COMPENSATION_ORDER.AMOUNT));

        response.setPayBankName(record.get(LOAN_CARD_COMPENSATION_ORDER.BANK_NAME));
        response.setPayBankCardNo(PhoneNumNideUtil.hideBankCard(record.get(LOAN_CARD_COMPENSATION_ORDER.CARD_NO)));
        //总的订单状态
        int status = record.get(LOAN_CARD_COMPENSATION_ORDER.STATUS);
        if (status == CardCompensationOrderStatus.PAYED){
            response.setPayStatus(ORDER_STATUS_MAP.get(CardCompensationOrderStatus.PAYED));
        }else if (status == CardCompensationOrderStatus.ALLIN_PROCESSING){
            response.setPayStatus(ORDER_STATUS_MAP.get(CardCompensationOrderStatus.ALLIN_PROCESSING));
        }else if (status == CardCompensationOrderStatus.ALLIN_SUCCESS){
            response.setPayStatus(ORDER_STATUS_MAP.get(CardCompensationOrderStatus.PAYED));
            response.setWithdrawStatus(ORDER_STATUS_MAP.get(CardCompensationOrderStatus.ALLIN_SUCCESS));
        }else{
            response.setPayStatus(ORDER_STATUS_MAP.get(CardCompensationOrderStatus.PAYED));
            response.setWithdrawStatus(ORDER_STATUS_MAP.get(status));
        }

        if (record.get(LOAN_CARD_COMPENSATION_ORDER.ORDER_TYPE) == 1){
            response.setWithdrawBankName(record.get(WITHDRAW_BANK_NAME,String.class));
            response.setWithdrawBankCardNo(PhoneNumNideUtil.hideBankCard(record.get(WITHDRAW_BANK_NUM,String.class)));
        }else{
            response.setWithdrawBankName(response.getPayBankName());
            response.setWithdrawBankCardNo(PhoneNumNideUtil.hideBankCard(response.getPayBankCardNo()));
        }

        response.setChannel_from(record.get(LOAN_CARD_COMPENSATION_ORDER.CHANNEL_FROM));
        return response;
    }


    /**
     * 根据请求条件，构造查询
     */
    private SelectQuery createQuery(CreditCompensatoryWithdrawOrderRequest searchRequest){

        Table orderTable = generateSelect(searchRequest).asTable("order");
        Table withdrawTable = generateCardSelect().asTable("withdraw");

        return dslContext.select(
                orderTable.fields()
                ).select(
                        withdrawTable.fields()
                ).from(orderTable)
                .leftJoin(withdrawTable).on(
                        orderTable.field(LOAN_CARD_COMPENSATION_ORDER.WITHDRAW_NO).eq(
                                withdrawTable.field(WITHDRAW_NO)
                        ))
                .getQuery();
    }

    private SelectQuery<Record> generateSelect(CreditCompensatoryWithdrawOrderRequest searchRequest) {
        Condition condition = DSL.trueCondition();
        List<SelectField<?>> selectFields = new ArrayList<>();
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.CTIME));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.ID));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.REGISTRATION_NO));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.CARD_NO));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.WITHDRAW_NO));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.MOBNUM));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.IDCARD));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.PETNAME));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.AMOUNT));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.TYPE));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.ORDER_TYPE));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.STATUS));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.PLATFORM));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.PRODUCT_ID));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.CHANNEL));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.CHANNEL_FROM));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.REMARK));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.BANK_NAME));
        selectFields.add(DSL.field(LOAN_CARD_COMPENSATION_ORDER.BANK_MOBILE_NUM));

        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.ID,condition,searchRequest.getOrderId());
        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.CHANNEL_FROM,condition,searchRequest.getChannel_from());
        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.PRODUCT_ID,condition,searchRequest.getProduct_id());
        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.PETNAME,condition,searchRequest.getPetname());
        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.BANK_MOBILE_NUM,condition,searchRequest.getMobnum());
        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.IDCARD,condition,searchRequest.getIdcard());
        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.ORDER_TYPE,condition,searchRequest.getOrderType());
        condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.CHANNEL,condition,searchRequest.getChannel_id());

        //对扣款状态与打款状态进行处理选择
        if (searchRequest.getPayStatus() != null && searchRequest.getWithdrawStatus() == null){
            if (searchRequest.getPayStatus() == CardCompensationOrderStatus.ALLIN_PROCESSING){
                condition = checkConditions(LOAN_CARD_COMPENSATION_ORDER.STATUS,condition,CardCompensationOrderStatus.ALLIN_PROCESSING);
            }else{
                condition = condition.and(LOAN_CARD_COMPENSATION_ORDER.STATUS.in(
                        CardCompensationOrderStatus.PAYED,
                        CardCompensationOrderStatus.ALLIN_SUCCESS,
                        CardCompensationOrderStatus.ALLIN_FAIL,
                        CardCompensationOrderStatus.ALLIN_EXCEPTION
                ));
            }
        }
        if (searchRequest.getWithdrawStatus()!=null){
            condition = condition.and(LOAN_CARD_COMPENSATION_ORDER.STATUS.eq(searchRequest.getWithdrawStatus()));
        }

        //时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        if (Objects.nonNull(searchRequest.getStartDate())) {
            condition = condition.and(DSL.field(LOAN_CARD_COMPENSATION_ORDER.CTIME).gt(
                    Timestamp.valueOf(sdf.format(searchRequest.getStartDate()) + " 00:00:00")));
        }
        if( Objects.nonNull(searchRequest.getEndDate()) ){
            condition = condition.and(DSL.field(LOAN_CARD_COMPENSATION_ORDER.CTIME).lt(
                    Timestamp.valueOf(sdf.format(searchRequest.getEndDate()) + " 23:59:59")));
        }

        condition = condition.and(DSL.field(LOAN_CARD_COMPENSATION_ORDER.TYPE).eq(20));
        condition = condition.and(DSL.field(LOAN_CARD_COMPENSATION_ORDER.STATUS).gt(11));

        return dslContext.select(selectFields)
                .from(LOAN_CARD_COMPENSATION_ORDER)
                .where(condition)
                .orderBy(LOAN_CARD_COMPENSATION_ORDER.CTIME.desc())
                .getQuery();
    }

    /**
     * 创建检查条件
     */
    private Condition checkConditions(TableField tableField,Condition condition,Object value){
        if (value != null && !value.equals("")){
            condition = condition.and(tableField.eq(value));
        }
        return condition;
    }


    private SelectQuery<Record> generateCardSelect() {
        List<SelectField<?>> selectFields = new ArrayList<>();
        selectFields.add(DSL.field(LOAN_COMPENSATION_USER_CARD.BANK).as(WITHDRAW_BANK_NAME));
        selectFields.add(DSL.field(LOAN_COMPENSATION_USER_CARD.CARD_NUM).as(WITHDRAW_BANK_NUM));
        selectFields.add(DSL.field(LOAN_COMPENSATION_USER_CARD.REGISTRATION_NO).as(WITHDRAW_NO));
        return dslContext.select(selectFields)
                .from(LOAN_COMPENSATION_USER_CARD)
                .getQuery();
    }
}
